package com.info.zhiduoduo.pay.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.info.zhiduoduo.common.configs.ZhaoShangPayConfig;
import com.info.zhiduoduo.common.constants.SmartResult;
import com.info.zhiduoduo.common.constants.StatusMsg;
import com.info.zhiduoduo.common.exception.Asserts;
import com.info.zhiduoduo.common.exception.SmartException;
import com.info.zhiduoduo.common.utils.RandomUtil;
import com.info.zhiduoduo.common.utils.StringUtil;
import com.info.zhiduoduo.pay.formbean.zhaoshangbankpay.*;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.common.HeadReqDTO;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.common.RequestDTO;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.common.pay.DetailedInfo;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.common.PatternInfo;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.common.pay.SummaryInfo;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.common.query.Account;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.common.query.Detailed;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.common.query.Outline;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.common.query.Result;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.common.query.Retreat;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.common.query.TransactionCode;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.request.agentpay.*;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.response.agentpay.AccountInfoResDTO;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.response.agentpay.PayDetailedDTO;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.response.agentpay.PayResDTO;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.response.agentpay.PayResultResDTO;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.response.agentpay.RetreatDTO;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.response.agentpay.TransactionCodeResDTO;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.response.agentpay.TransactionOutlineResDTO;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.service.ZhaoShangBankPayApiService;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.util.DCHelper;
import com.info.zhiduoduo.repository.entity.pay.PaymentMerchant;

import org.springframework.stereotype.Service;

import java.util.List;

import javax.annotation.Resource;

import lombok.extern.slf4j.Slf4j;



@Slf4j
@Service
public class ZhaoShangBankPayService {

	@Resource
	ZhaoShangBankPayApiService zhaoShangBankPayApiService;

	@Resource
	ZhaoShangPayConfig zhaoShangPayConfig;

	/**
	 * 招商银行代付
	 * @param formBean
	 * @return
	 */
	public SmartResult<PayResDTO> agentPay(ZhaoShangAgentPayFormBean formBean) {
		PaymentMerchant paymentMerchant = new PaymentMerchant().selectById(formBean.getPaymentMerchant());
		log.info("获取到的支付商户:{}", JSON.toJSONString(paymentMerchant));
		Asserts.notNull(paymentMerchant, StatusMsg.StatusMsg_459);
		//构建head信息
		HeadReqDTO headReqDTO = HeadReqDTO.of(zhaoShangPayConfig.getAgentPay(),paymentMerchant.getMerchantNo());
		//构建body中模式信息
		List<PatternInfo> patternInfo = PatternInfo.ofLost(paymentMerchant.getPatternCode());
		//构建body中汇总信息
		List<SummaryInfo> summaryInfo = SummaryInfo.ofList(formBean,paymentMerchant);
		//构建body中明细信息
		List<DetailedInfo> detailedInfo = DetailedInfo.ofList(formBean);
		//构建body
		AgentPayReqDTO agentPayReqDTO = new AgentPayReqDTO();
		agentPayReqDTO.setNtbusmody(patternInfo)
				.setNtagcsaix1(summaryInfo)
				.setNtagcsaix2(detailedInfo);
		RequestDTO<AgentPayReqDTO> dto = new RequestDTO<>();
		dto.setHead(headReqDTO);
		dto.setBody(agentPayReqDTO);
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("request",dto);
		PayResDTO payResDTO = null;
		try {
			payResDTO = zhaoShangBankPayApiService.agentPay(jsonObject,paymentMerchant.getMerchantNo());
		} catch (SmartException e) {
			if (e.getState() == StatusMsg.StatusMsg_472.state) {
				// 网络异常
				return SmartResult.fail(StatusMsg.StatusMsg_472);
			} else {
				// 支付有结果，但报文异常
				return SmartResult.fail(StatusMsg.StatusMsg_465);
			}
		}
		if (null == payResDTO) {
			return SmartResult.fail(StatusMsg.StatusMsg_465);
		}
		return SmartResult.success(payResDTO);
	}

	/**
	 * 查询交易概要信息
	 * @param formBean
	 * @return
	 */
	public SmartResult<TransactionOutlineResDTO> queryTransactionOutline(QueryPayResultFormBean formBean){
		PaymentMerchant paymentMerchant = new PaymentMerchant().selectById(formBean.getPaymentMerchant());
		log.info("获取到的支付商户:{}", JSON.toJSONString(paymentMerchant));
		//构建head信息
		HeadReqDTO headReqDTO = HeadReqDTO.of(zhaoShangPayConfig.getQueryTransactionOutline(),paymentMerchant.getMerchantNo());
		//构建body
		List<Outline> outlineList = Outline.ofList(formBean, paymentMerchant);
		QueryTransactionOutlineReqDTO queryTransactionOutlineReqDTO = new QueryTransactionOutlineReqDTO();
		queryTransactionOutlineReqDTO.setNtagcinny1(outlineList);
		RequestDTO<QueryTransactionOutlineReqDTO> dto = new RequestDTO<>();
		dto.setHead(headReqDTO);
		dto.setBody(queryTransactionOutlineReqDTO);
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("request",dto);
		TransactionOutlineResDTO transactionOutlineResDTO = zhaoShangBankPayApiService.queryTransactionOutline(jsonObject,paymentMerchant.getMerchantNo(),formBean.getTradeNo());
		if(null == transactionOutlineResDTO){
			return SmartResult.fail(StatusMsg.StatusMsg_471);
		}
		return SmartResult.success(transactionOutlineResDTO);
	}

	/**
	 * 查询交易结果
	 * @param formBean
	 * @return
	 */
	public SmartResult<PayResultResDTO> queryAgentPay(QueryPayResultFormBean formBean){
		PaymentMerchant paymentMerchant = new PaymentMerchant().selectById(formBean.getPaymentMerchant());
		log.info("获取到的支付商户:{}", JSON.toJSONString(paymentMerchant));
		//构建head信息
		HeadReqDTO headReqDTO = HeadReqDTO.of(zhaoShangPayConfig.getQueryAgentPay(),paymentMerchant.getMerchantNo());
		//构建body
		List<Result> resultList = Result.ofList(formBean);
		QueryAgentPayReqDTO queryAgentPayReqDTO = new QueryAgentPayReqDTO();
		queryAgentPayReqDTO.setNtagcinyx1(resultList);
		RequestDTO<QueryAgentPayReqDTO> dto = new RequestDTO<>();
		dto.setHead(headReqDTO);
		dto.setBody(queryAgentPayReqDTO);
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("request",dto);
		PayResultResDTO payResultResDTO = zhaoShangBankPayApiService.queryAgentPay(jsonObject,paymentMerchant.getMerchantNo());
		if(null == payResultResDTO){
			return SmartResult.fail(StatusMsg.StatusMsg_466);
		}
		return SmartResult.success(payResultResDTO);
	}

	/**
	 * 查询交易流水
	 * @param formBean
	 * @return
	 */
	public SmartResult<PayDetailedDTO> queryAgentPayDetailed(QueryPayResultFormBean formBean){
		PaymentMerchant paymentMerchant = new PaymentMerchant().selectById(formBean.getPaymentMerchant());
		log.info("获取到的支付商户:{}", JSON.toJSONString(paymentMerchant));
		//构建head信息
		HeadReqDTO headReqDTO = HeadReqDTO.of(zhaoShangPayConfig.getQueryAgentPayDetailed(),paymentMerchant.getMerchantNo());
		//构建body
		List<Detailed> detailedList = Detailed.ofList(formBean);
		QueryAgentPayDetailedReqDTO detailedReqDTO = new QueryAgentPayDetailedReqDTO();
		detailedReqDTO.setNtagdinfy1(detailedList);
		RequestDTO<QueryAgentPayDetailedReqDTO> dto = new RequestDTO<>();
		dto.setHead(headReqDTO);
		dto.setBody(detailedReqDTO);
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("request",dto);
		PayDetailedDTO payDetailedDTO = zhaoShangBankPayApiService.queryAgentPayDetailed(jsonObject,paymentMerchant.getMerchantNo());
		if(null == payDetailedDTO){
			return SmartResult.fail(StatusMsg.StatusMsg_467);
		}
		return SmartResult.success(payDetailedDTO);
	}

	/**
	 * 查询代发退票
	 * @param formBean
	 * @return
	 */
	public SmartResult<RetreatDTO> queryAgentPayRetreat(QueryPayResultFormBean formBean){
		PaymentMerchant paymentMerchant = new PaymentMerchant().selectById(formBean.getPaymentMerchant());
		log.info("获取到的支付商户:{}", JSON.toJSONString(paymentMerchant));
		//构建head信息
		HeadReqDTO headReqDTO = HeadReqDTO.of(zhaoShangPayConfig.getQueryAgentPayRetreat(),paymentMerchant.getMerchantNo());
		//构建body
		List<Retreat> retreatList = Retreat.ofList(paymentMerchant,formBean.getOrderTime());
		QueryAgentPayRetreatReqDTO retreatReqDTO = new QueryAgentPayRetreatReqDTO();
		retreatReqDTO.setNtagdrfdy1(retreatList);
		RequestDTO<QueryAgentPayRetreatReqDTO> dto = new RequestDTO<>();
		dto.setHead(headReqDTO);
		dto.setBody(retreatReqDTO);
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("request",dto);
		RetreatDTO retreatDTO = zhaoShangBankPayApiService.queryAgentPayRetreat(jsonObject,paymentMerchant.getMerchantNo());
		if(null == retreatDTO){
			return SmartResult.fail(StatusMsg.StatusMsg_470);
		}
		return SmartResult.success(retreatDTO);
	}

	/**
	 * 查询银行账户详细信息
	 * @param merchantId
	 * @return
	 */
	public SmartResult<AccountInfoResDTO> queryAccountInfo(int merchantId){
		PaymentMerchant paymentMerchant = new PaymentMerchant().selectById(merchantId);
		log.info("获取到的支付商户:{}", JSON.toJSONString(paymentMerchant));
		//构建head信息
		HeadReqDTO headReqDTO = HeadReqDTO.of(zhaoShangPayConfig.getQueryAccountInfo(),paymentMerchant.getMerchantNo());
		//构建body
		List<Account> accountList = Account.ofList(paymentMerchant);
		QueryAccountReqDTO accountReqDTO = new QueryAccountReqDTO();
		accountReqDTO.setNtqacinfx(accountList);
		RequestDTO<QueryAccountReqDTO> dto = new RequestDTO<>();
		dto.setHead(headReqDTO);
		dto.setBody(accountReqDTO);
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("request",dto);
		AccountInfoResDTO accountInfoResDTO = zhaoShangBankPayApiService.queryAccountInfo(jsonObject,paymentMerchant.getMerchantNo());
		if(null == accountInfoResDTO){
			return SmartResult.fail(StatusMsg.StatusMsg_464);
		}
		return SmartResult.success(accountInfoResDTO);
	}

	/**
	 * 查询银行账号交易代码
	 * @param formBean
	 * @return
	 */
	public SmartResult<TransactionCodeResDTO> queryTransactionCode(QueryTransactionCodeFormBean formBean){
		PaymentMerchant paymentMerchant = new PaymentMerchant().selectById(formBean.getMerchantId());
		log.info("获取到的支付商户:{}", JSON.toJSONString(paymentMerchant));
		//构建head信息
		HeadReqDTO headReqDTO = HeadReqDTO.of(zhaoShangPayConfig.getQueryTransactionCode(),paymentMerchant.getMerchantNo());
		//构建body
		List<TransactionCode> codeList = TransactionCode.ofList(paymentMerchant);
		QueryTransactionCodeReqDTO transactionCodeReqDTO = new QueryTransactionCodeReqDTO();
		transactionCodeReqDTO.setNtagtls2x(codeList);
		RequestDTO<QueryTransactionCodeReqDTO> dto = new RequestDTO<>();
		dto.setHead(headReqDTO);
		dto.setBody(transactionCodeReqDTO);
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("request",dto);
		TransactionCodeResDTO transactionCodeResDTO = zhaoShangBankPayApiService.queryTransactionCode(jsonObject,paymentMerchant.getMerchantNo());
		if(null == transactionCodeResDTO){
			return SmartResult.fail(StatusMsg.StatusMsg_468);
		}
		return SmartResult.success(transactionCodeResDTO);
	}

	/**
	 * 账户交易信息查询
	 * @param formBean
	 * @return
	 */
	public SmartResult queryTransactionInfo(QueryTransactionInfoFormBean formBean){
		PaymentMerchant paymentMerchant = new PaymentMerchant().selectById(formBean.getMerchantId());
		Asserts.notNull(paymentMerchant, StatusMsg.StatusMsg_475);

		String refnbr = zhaoShangBankPayApiService.queryTransactionInfo(paymentMerchant,formBean);
		if(StringUtil.isEmpty(refnbr)){
			return SmartResult.fail(StatusMsg.StatusMsg_487);
		}
		return SmartResult.success(refnbr);
	}

	/**
	 * 查询银行电子回单
	 * @param formBean
	 * @return
	 */
	public SmartResult queryElectronReceiptFile(QueryElectronicReceiptFormBean formBean){
		PaymentMerchant paymentMerchant = new PaymentMerchant().selectById(formBean.getMerchantId());
		Asserts.notNull(paymentMerchant, StatusMsg.StatusMsg_475);

		String filePath = zhaoShangBankPayApiService.queryElectronReceiptFile(paymentMerchant,formBean.getRefnbr(),
				formBean.getQuedat(),formBean.getTradeNo());
		if(StringUtil.isEmpty(filePath)){
			return SmartResult.fail(StatusMsg.StatusMsg_488);
		}
		return SmartResult.success(filePath);
	}

	/**
	 * 查询账户交易信息查询得到银行流水号/生成电子回单
	 * @param formBean
	 * @return
	 */
	public SmartResult queryReqnbrCreatElectronReceiptFile(QueryTransactionInfoFormBean formBean){
		PaymentMerchant paymentMerchant = new PaymentMerchant().selectById(formBean.getMerchantId());
		Asserts.notNull(paymentMerchant, StatusMsg.StatusMsg_475);

		String refnbr = zhaoShangBankPayApiService.queryTransactionInfo(paymentMerchant,formBean);
		Asserts.notNull(refnbr,StatusMsg.StatusMsg_487);

		String filePath = zhaoShangBankPayApiService.queryElectronReceiptFile(paymentMerchant,refnbr,
				formBean.getQueryDate(), formBean.getTradeNo());
		Asserts.notNull(filePath,StatusMsg.StatusMsg_488);
		return SmartResult.success(filePath);
	}

	/**
	 * 代发明细对账单查询请求
	 */
	public SmartResult queryReceiptFile(QueryReceiptFormBean formBean){
		PaymentMerchant paymentMerchant = new PaymentMerchant().selectById(formBean.getMerchantId());
		Asserts.notNull(paymentMerchant, StatusMsg.StatusMsg_475);
		//构建head信息
		JSONObject head = new JSONObject();
		head.put("funcode","DCAGPPDF");
		head.put("reqid", DCHelper.getTime() + RandomUtil.randomNum(5));
		head.put("userid",paymentMerchant.getMerchantNo());
		//构建body
		JSONObject body = new JSONObject();
		body.put("payeac",paymentMerchant.getBankCard());
		//	交易开始日期
		body.put("begdat",formBean.getTradeDate());
		body.put("enddat",formBean.getTradeDate());
		body.put("buscod", "N03020");
		body.put("busmod", "00002");
		body.put("prtmod", formBean.getPrtmod());
		body.put("begidx", formBean.getBegidx());
		// request
		JSONObject request = new JSONObject();
		request.put("body",body);
		request.put("head",head);

		JSONObject putJson = new JSONObject();
		putJson.put("request",request);
		log.info("代发明细对账单查询请求对象:" + putJson.toString());
		String result = zhaoShangBankPayApiService.pushPost(putJson,paymentMerchant.getMerchantNo());

		// 处理请求返回结果
        if (StringUtil.isEmpty(result)) {
            return SmartResult.fail("查询-代发明细对账单请求查询-失败！失败原因：请求返回为空！");
        }

        //将结果转为json
        JSONObject object = JSON.parseObject(result);
        log.info("代发明细对账单查询请求对象-请求返回结果:" + object.toString());
        JSONObject response = object.getJSONObject("response");
        //获取head信息
        JSONObject resHead = response.getJSONObject("head");
        if(null == resHead){
			return SmartResult.fail("查询-代发明细对账单请求查询-失败！失败原因：请求返回为空！");
        }
        if(!"SUC0000".equals(resHead.getString("resultcode"))){
			return SmartResult.fail("查询-代发明细对账单请求查询-失败！失败原因：" + resHead.getString("resultmsg"));
        }
        //获取body信息
        JSONObject resBody = response.getJSONObject("body");
        //获取结果
        return SmartResult.success(resBody.getString("printid"));
	}

	public SmartResult printReceiptFile(QueryReceiptFormBean formBean){
		PaymentMerchant paymentMerchant = new PaymentMerchant().selectById(formBean.getMerchantId());
		Asserts.notNull(paymentMerchant, StatusMsg.StatusMsg_475);
		//构建head信息
		JSONObject head = new JSONObject();
		head.put("funcode","DCTASKID");
		head.put("reqid", DCHelper.getTime() + RandomUtil.randomNum(5));
		head.put("userid",paymentMerchant.getMerchantNo());
		//构建body
		JSONObject body = new JSONObject();
		body.put("taskid",formBean.getPrintid());
		// request
		JSONObject request = new JSONObject();
		request.put("body",body);
		request.put("head",head);
		JSONObject putJson = new JSONObject();
		putJson.put("request",request);

		log.info("代发明细对账单处理结果-查询请求对象:" + putJson.toString());
		String result = zhaoShangBankPayApiService.pushPost(putJson,paymentMerchant.getMerchantNo());

		// 处理请求返回结果
        if (StringUtil.isEmpty(result)) {
            return SmartResult.fail("查询-代发明细对账单处理结果-失败！失败原因：请求返回为空！");
        }
        //将结果转为json
        JSONObject object = JSON.parseObject(result);
        log.info("代发明细对账单处理结果-请求返回结果:" + object.toString());
        JSONObject response = object.getJSONObject("response");
        //获取head信息
        JSONObject resHead = response.getJSONObject("head");
        if(null == resHead){
			return SmartResult.fail("查询-代发明细对账单处理结果-失败！失败原因：head为空");
        }
        if(!"SUC0000".equals(resHead.getString("resultcode"))){
			return SmartResult.fail("查询-代发明细对账单处理结果-失败！失败原因：" + resHead.getString("resultmsg"));
        }
        //获取body信息
        JSONObject resBody = response.getJSONObject("body");
        //获取结果
        return SmartResult.success(resBody.getString("printid"));
	}

}
